﻿using SelfMadeMillionaire.Core;
using SelfMadeMillionaire.Core.Entities;
using SelfMadeMillionaire.Core.Enums;
using SelfMadeMillionaire.Core.Services;
using SelfMadeMillionaire.Web.Infrastructure.Controllers;
using SelfMadeMillionaire.Web.Infrastructure.Formatters;
using SelfMadeMillionaire.Web.Infrastructure.ViewModels.Newss;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using PagedList;
using System.Globalization;
using SelfMadeMillionaire.Core.Specifications.Newss;

namespace SelfMadeMillionaire.Web.Infrastructure.Controllers.Admin
{
	public class NewsController : AdminController
	{
		INewsService _newsService;
        INewsProductService _newsProductService;

        public NewsController(INewsService NewsService, INewsProductService newsProductService)
		{
			_newsService = NewsService;
            _newsProductService = newsProductService;
		}

        class NewsFilterSave
        {
            public DateTime? StartDate;
            public DateTime? EndDate;
            public ProductType? SelectedProduct;
            public string Title;
            public int? Page;
            public byte? MinAccessLevel;
            public string Sort;
        }

        public ActionResult Index(DateTime? startDate, DateTime? endDate, ProductType? selectedProduct, string title, int? page, byte? minAccessLevel, string sort)
        {
            if (Session["UseNewsFilter"] != null && Session["NewsFilter"] != null)
            {
                Session["UseNewsFilter"] = null;
                var filter = Session["NewsFilter"] as NewsFilterSave;

                startDate = filter.StartDate;
                endDate = filter.EndDate;
                selectedProduct = filter.SelectedProduct;
                title = filter.Title;
                page = filter.Page;
                minAccessLevel = filter.MinAccessLevel;
                sort = filter.Sort;
            }
            else
            {
                Session["NewsFilter"] = new NewsFilterSave()
                {
                    StartDate = startDate,
                    EndDate = endDate,
                    SelectedProduct = selectedProduct,
                    Title = title,
                    Page = page,
                    MinAccessLevel = minAccessLevel,
                    Sort = sort
                };
            }


            int pageIndex = page ?? 1;
            int pageSize = 10;
            
            startDate = startDate ?? DateTime.Today.AddMonths(-1);
            endDate = endDate ?? DateTime.Today;

            var model = new NewsListViewModel
            {
                StartDate = startDate,
                EndDate = endDate,
                ProductTypes = GetProductTypes(selectedProduct),
                AccessLevels = GetAccessLevelsFilter(minAccessLevel.HasValue ? minAccessLevel.ToString() : null),
                Title = title,
                SortOrder = sort
            };
            IEnumerable<News> list = _newsService.GetList(new NewsListSpecification(startDate, endDate, selectedProduct, title, null, (SubscriptionType?)minAccessLevel));
            if (!string.IsNullOrEmpty(sort))
            {
                string[] sortArr = sort.Split(',');
                if (sortArr[1] == "0")
                {

                    switch (sortArr[0])
                    {
                        case "0":
                            list = list.OrderBy(i => i.Date);
                            break;
                        case "1":
                            list = list.OrderBy(i => ProductTypeFormatter.GetProductTypeName((ProductType)Enum.Parse(typeof(ProductType), i.ProductType.ToString())));
                            break;
                        case "2":
                            list = list.OrderBy(i => i.MinAccessLevel);
                            break;
                        case "3":
                            list = list.OrderBy(i => i.Title);
                            break;
                        case "4":
                            list = list.OrderBy(i => i.ExternalUrl);
                            break;
                    }

                }
                else
                {
                    switch (sortArr[0])
                    {
                        case "0":
                            list = list.OrderByDescending(i => i.Date);
                            break;
                        case "1":
                            list = list.OrderByDescending(i => ProductTypeFormatter.GetProductTypeName((ProductType)Enum.Parse(typeof(ProductType), i.ProductType.ToString())));
                            break;
                        case "2":
                            list = list.OrderByDescending(i => i.MinAccessLevel);
                            break;
                        case "3":
                            list = list.OrderByDescending(i => i.Title);
                            break;
                        case "4":
                            list = list.OrderByDescending(i => i.ExternalUrl);
                            break;
                    }
                }
            }
            model.News = list.ToPagedList(pageIndex, pageSize);

            if (Request.IsAjaxRequest())
                return PartialView("NewsList", model);

            return View(model);
        }

        [HttpGet]
        public ActionResult Add()
        {
            var model = new NewsEditViewModel
            {
                News = new News() { Date = DateTime.Today },
                ProductTypes = GetProductTypes(),
                AccessLevels = GetAccessLevels(null),
                SelectedProducts = new List<int>()
            };

            Session["UseNewsFilter"] = true;
            return View(model);
        }

        [ValidateInput(false)]
        [HttpPost]
        public ActionResult Add(NewsEditViewModel model)
        {
            if (ModelState.IsValid)
            {
                model.News.Products = new List<NewsProduct>();
                if (model.SelectedProducts != null)
                {
                    model.SelectedProducts.ForEach(x => model.News.Products.Add(new NewsProduct() { ProductType = (byte)x }));
                }

                _newsService.Add(model.News);
                return RedirectToAction("Index");
            }

            model.ProductTypes = GetProductTypes((ProductType)model.News.ProductType);
            model.AccessLevels = GetAccessLevels(model.MinAccessLevel);
            return View(model);
        }

        [HttpGet]
        public ActionResult Edit(int id, DateTime? startDate, DateTime? endDate, ProductType? selectedProduct, string title, byte? minAccessLevel, string sort)
        {
            var news = _newsService.Get(id);

            var model = new NewsEditViewModel
            {
                News = news,
                ProductTypes = GetProductTypes((ProductType)news.ProductType),
                SelectedProduct = selectedProduct,
                StartDate = startDate,
                EndDate = endDate,
                Title = title,
                MinAccessLevel = minAccessLevel,
                AccessLevels = GetAccessLevels(news.MinAccessLevel),
                SortOrder = sort,
                SelectedProducts = news.Products.Select(x => (int)x.ProductType).ToList()
            };

            Session["UseNewsFilter"] = true;
            return View(model);
        }

        [ValidateInput(false)]
        [HttpPost]
        public ActionResult Edit(NewsEditViewModel model)
        {
            if (ModelState.IsValid)
            {
                model.News.Products = _newsService.Get(model.News.ID).Products;
                model.News.Products.ToList().ForEach(x => _newsProductService.Remove(x.ID));
                if (model.SelectedProducts != null)
                {
                    model.SelectedProducts.ForEach(x => model.News.Products.Add(new NewsProduct() { ProductType = (byte)x }));
                }

                _newsService.Update(model.News);
                
                string startDate = model.StartDate.HasValue ? model.StartDate.Value.ToString(Constants.DATE_FORMAT) : null;
                string endDate = model.EndDate.HasValue ? model.EndDate.Value.ToString(Constants.DATE_FORMAT) : null;

                return RedirectToAction("Index", new { startDate = startDate, endDate = endDate, selectedProduct = model.SelectedProduct, title = model.Title, minAccessLevel = model.MinAccessLevel, sort = model.SortOrder });
            }

            model.ProductTypes = GetProductTypes((ProductType)model.News.ProductType);
            model.AccessLevels = GetAccessLevels(model.MinAccessLevel);
            return View(model);
        }

        [HttpGet]
        public string Delete(int id)
        {
            _newsService.Remove(id);
            return "Completed successfully!";
        }
	}
}
